package com.boarsoft.boar.app.biz;

import java.util.Arrays;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.boar.app.AppBiz;
import com.boarsoft.boar.app.AppLibBiz;
import com.boarsoft.boar.entity.AppInfo;
import com.boarsoft.boar.entity.AppLib;
import com.boarsoft.boar.entity.LibInfo;
import com.boarsoft.boar.lib.LibBiz;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.hibernate.biz.SimpleBizImpl;

/**
 * 根据appId查LibInfo
 * 
 * @author Mac_J
 *
 */
@Component
public class AppLibBizImpl extends SimpleBizImpl implements AppLibBiz {

	@Autowired
	protected AppBiz appBiz;
	@Autowired
	protected LibBiz libBiz;

	@Override
	@Transactional(readOnly = true)
	public PagedResult<AppLib> list(String appId, String key, String orderBy, int pageNo, int pageSize) {
		StringBuffer sb = new StringBuffer();
		sb.append("a.id = '").append(appId).append("'");
		if (Util.strIsNotEmpty(key)) {
			sb.append(" and (l.code like '%").append(key);
			sb.append("%' or l.name like '%").append(key);
			sb.append("%' or l.memo like '%").append(key);
			sb.append("%')");
		}
		String hql = new StringBuffer().append("select count(al) from ").append(AppLib.class.getName())
				.append(" al join al.lib l join al.app a ").append(" where ").append(sb).toString();
		int total = dao.getTotal(hql);
		if (Util.strIsNotEmpty(orderBy)) {
			String ob = Util.array2str(("l." + orderBy).replaceAll(",", ",").split(","), ",");
			sb.append(" order by ").append(ob);
		} else {
			sb.append(" order by l.name");
		}
		hql = new StringBuffer().append("select al from ").append(AppLib.class.getName())
				.append(" al join al.lib l join al.app a ").append(" where ").append(sb).toString();
		List<AppLib> lt = dao.list(hql, pageNo, pageSize);
		return new PagedResult<AppLib>(total, lt, pageNo, pageSize);
	}

	@Override
	@Transactional
	public void save(AppLib o) {
		if (Util.strIsEmpty(o.getId())) {
			dao.save(o);
		} else {
			dao.merge(o);
		}
	}

	/**
	 * 新增一条一对多关联关系记录 1，可能是一个appId对多个libId 2，可能是一个libId对多个appId
	 *
	 * @param appIds--由英文逗号分隔的多个libId组成
	 * @param libIds--由英文逗号分隔的多个libId组成
	 */
	@Override
	@Transactional
	public void save(String appIds, String libIds) {
		String APP_IDS[] = appIds.split(",");
		String LIB_IDS[] = libIds.split(",");
		int APP_IDS_SIZE = APP_IDS.length;
		int LIB_IDS_SIZE = LIB_IDS.length;
		if (APP_IDS_SIZE == 1 && LIB_IDS_SIZE > 1) {
			for (String LIB_ID : LIB_IDS) {
				AppLib appLib = new AppLib();
				AppInfo app = appBiz.get(appIds);
				appLib.setLibPath(app.getLibPath());
				appLib.setApp(app);
				appLib.setLib(libBiz.get(LIB_ID));
				this.save(appLib);
			}
			return;
		}
		if (LIB_IDS_SIZE == 1 && APP_IDS_SIZE > 1) {
			for (String APP_ID : APP_IDS) {
				AppLib appLib = new AppLib();
				AppInfo app = appBiz.get(APP_ID);
				appLib.setLibPath(app.getLibPath());
				appLib.setApp(app);
				appLib.setLib(libBiz.get(libIds));
				this.save(appLib);
			}
			return;
		}
		if (LIB_IDS_SIZE == 1 && APP_IDS_SIZE == 1) {
			AppLib appLib = new AppLib();
			AppInfo app = appBiz.get(appIds);
			appLib.setLibPath(app.getLibPath());
			appLib.setApp(app);
			appLib.setLib(libBiz.get(libIds));
			this.save(appLib);
			return;
		}
		throw new IllegalArgumentException("参数不合法");
	}

	@Override
	@Transactional
	public void delete(String id) {
		dao.delete(AppLib.class, id);
	}

	@Override
	@Transactional(readOnly = true)
	public AppLib get(String id) {
		return (AppLib) dao.get(AppLib.class, id);
	}

	@Override
	@Transactional(readOnly = true)
	public List<AppLib> find(String appId, String libId) {
		StringBuilder sb = new StringBuilder();
		if (Util.strIsNotEmpty(appId)) {
			sb.append(" and a.id='").append(appId).append("'");
		}
		if (Util.strIsNotEmpty(libId)) {
			sb.append(" and l.id='").append(libId).append("'");
		}

		String ql = "select al from " + AppLib.class.getName() + " al join al.lib l join al.app a " + " where 1=1 " + sb;
		return dao.list(ql);
	}

	/**
	 * 给一个新的应用新增一个已有应用与库包Id之间的关联关系 即是：复制一个已有应用与库包id之间的关联关系到一个新的应用
	 * 新应用就有了与老应用一样的库包关联
	 */
	@Override
	public boolean copy(String oldAppId, String newAppId) {
		// 查找出老应用已有的关联关系信息
		List<AppLib> appLibs = this.find(oldAppId, null);
		if (appLibs == null || appLibs.size() == 0) {
			return false;
		}
		AppInfo app = appBiz.get(newAppId);
		for (AppLib appLib : appLibs) {
			AppLib al = new AppLib();
			al.setApp(app);
			al.setLib(appLib.getLib());
			al.setLibPath(appLib.getLibPath());
			this.save(al);
		}
		return true;
	}

	@Override
	@Transactional
	public int updateLibPath(String appId, String libId, String libPath) {
		List<AppLib> appLibs = this.find(appId, libId);
		if (appLibs == null || appLibs.size() == 0) {
			return 0;
		}
		AppLib appLib = appLibs.get(0);// 根据appId和libId两项信息查找出唯一记录
		appLib.setLibPath(libPath);
		return 1;
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional(readOnly = true)
	public List<AppLib> findByBatch(String appIds, String libIds) {
		StringBuffer hql = new StringBuffer();
		hql.append("select al from " + AppLib.class.getName() + " al join al.lib l join al.app a ").append("where 1=1 ");
		List<String> apps = null;
		List<String> libs = null;
		if (Util.strIsNotEmpty(appIds)) {
			apps = Arrays.asList(appIds.split(","));
			hql.append(" and a.id in :apps");
		}
		if (Util.strIsNotEmpty(libIds)) {
			libs = Arrays.asList(libIds.split(","));
			hql.append(" and l.id in :libs");
		}
		Session session = dao.getASession();
		Query<AppLib> query = session.createQuery(hql.toString());
		if (apps != null) {
			query.setParameterList("apps", apps);
		}
		if (libs != null) {
			query.setParameterList("libs", libs);
		}
		return query.list();
	}

	@Override
	@Transactional(readOnly = true)
	public List<LibInfo> list(String appId) {
		StringBuilder sb = new StringBuilder();
		sb.append("select distinct l from ");
		sb.append(AppInfo.class.getName()).append(" a join a.libs l join l.apps p");
		sb.append(" where a.id='").append(appId).append("'");
		return dao.list(sb.toString(), LibInfo.class);
	}
}